package cn.iocoder.yudao.module.system.controller.admin.datasource;

import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.datasource.core.DataSourceConfigDO;
import cn.iocoder.yudao.module.system.service.datasource.DynamicDataSourceTestService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;

@Tag(name = "管理后台 - 系统数据源测试")
@RestController
@RequestMapping("/system/datasource-test")
@Validated
@Slf4j
public class SystemDataSourceTestController {

    @Autowired
    private DynamicDataSourceTestService dynamicDataSourceTestService;

    @GetMapping("/test-current")
    @Operation(summary = "测试当前数据源连接")
    @PreAuthorize("@ss.hasPermission('system:datasource-config:query')")
    public CommonResult<String> testCurrentDataSource() {
        try {
            String result = dynamicDataSourceTestService.testCurrentDataSource();
            return success(result);
        } catch (Exception e) {
            log.error("测试当前数据源失败", e);
            return success("测试失败: " + e.getMessage());
        }
    }

    @PostMapping("/test-switch")
    @Operation(summary = "测试数据源切换功能")
    @PreAuthorize("@ss.hasPermission('system:datasource-config:switch')")
    public CommonResult<String> testDataSourceSwitch(@RequestBody TestDataSourceSwitchReqVO reqVO) {
        try {
            DataSourceConfigDO config = new DataSourceConfigDO(
                    reqVO.getDataSourceKey(),
                    reqVO.getUrl(),
                    reqVO.getUsername(),
                    reqVO.getPassword(),
                    reqVO.getType()
            );

            String sql = reqVO.getTestSql();
            if (sql == null || sql.trim().isEmpty()) {
                sql = "SELECT 1 as test_result"; // 默认测试SQL
            }

            String result = dynamicDataSourceTestService.testDataSourceSwitch(config, sql);
            return success(result);
        } catch (Exception e) {
            log.error("测试数据源切换失败", e);
            return success("测试失败: " + e.getMessage());
        }
    }

    @GetMapping("/create-test-config")
    @Operation(summary = "创建测试数据源配置")
    @PreAuthorize("@ss.hasPermission('system:datasource-config:query')")
    public CommonResult<DataSourceConfigDO> createTestDataSourceConfig() {
        try {
            DataSourceConfigDO config = dynamicDataSourceTestService.createTestDataSourceConfig();
            return success(config);
        } catch (Exception e) {
            log.error("创建测试配置失败", e);
            return success(null);
        }
    }

    /**
     * 测试数据源切换请求VO
     */
    public static class TestDataSourceSwitchReqVO {
        private String dataSourceKey = "test-datasource";
        private String url = "jdbc:mysql://127.0.0.1:3306/ruoyi-vue-pro?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true";
        private String username = "root";
        private String password = "123456";
        private String type = "MYSQL";
        private String testSql = "SELECT COUNT(*) as table_count FROM information_schema.tables WHERE table_schema = DATABASE()";

        // Getters and Setters
        public String getDataSourceKey() { return dataSourceKey; }
        public void setDataSourceKey(String dataSourceKey) { this.dataSourceKey = dataSourceKey; }

        public String getUrl() { return url; }
        public void setUrl(String url) { this.url = url; }

        public String getUsername() { return username; }
        public void setUsername(String username) { this.username = username; }

        public String getPassword() { return password; }
        public void setPassword(String password) { this.password = password; }

        public String getType() { return type; }
        public void setType(String type) { this.type = type; }

        public String getTestSql() { return testSql; }
        public void setTestSql(String testSql) { this.testSql = testSql; }
    }
}